import axios from 'axios'
import type { AxiosInstance } from 'axios'
import type { IInterceptors, IConfig } from './type'
import { ElLoading } from 'element-plus'
import { LoadingInstance } from 'element-plus/es/components/loading/src/loading'

const DEFAULT_LOADING = true
//创建封装axios类
class AxiosRequest {
  //axios实例
  instance: AxiosInstance
  //ElLoading实例
  loading?: LoadingInstance
  //是否需要loading
  isShowLoading: boolean
  //自定义拦截器
  interceptors?: IInterceptors

  constructor(config: IConfig) {
    //创建axios实例
    this.instance = axios.create(config)
    //默认为true
    this.isShowLoading = config.isShowLoading ?? DEFAULT_LOADING
    this.interceptors = config.interceptors
    //使用拦截器
    //从config中取出的拦截器是对应的实例的拦截器
    this.instance.interceptors.request.use(
      this.interceptors?.requestInterceptor,
      this.interceptors?.requestErrorInterceptor
    )
    this.instance.interceptors.response.use(
      this.interceptors?.responseInterceptor,
      this.interceptors?.responseErrorInterceptor
    )
    //添加所有的实例都有的拦截器
    this.instance.interceptors.request.use(
      (config) => {
        if (this.isShowLoading) {
          this.loading = ElLoading.service({
            text: '加载中...'
          })
        }
        return config
      },
      (err) => {
        return err
      }
    )
    this.instance.interceptors.response.use(
      (res) => {
        this.loading?.close()
        const data = res.data
        console.log(data)
        return data
      },
      (err) => {
        this.loading?.close()
        console.log('请求失败', err)
        return err
      }
    )
  }

  request<T>(config: IConfig<T>): Promise<T> {
    return new Promise((resolve, reject) => {
      //单个请求对请求config的处理
      if (config.interceptors?.requestInterceptor) {
        config = config.interceptors.requestInterceptor(config)
      }
      //判断是否需要显示loading
      if (config.isShowLoading === false) {
        this.isShowLoading = config.isShowLoading
      }
      this.instance
        .request<any, T>(config)
        .then((res) => {
          //单个请求对数据的处理
          if (config.interceptors?.responseInterceptor) {
            res = config.interceptors.responseInterceptor(res)
          }
          this.isShowLoading = DEFAULT_LOADING
          resolve(res)
        })
        .catch((err) => {
          this.isShowLoading = DEFAULT_LOADING
          reject(err)
        })
    })
  }
  get<T>(config: IConfig<T>): Promise<T> {
    return this.request<T>({ ...config, method: 'GET' })
  }

  post<T>(config: IConfig<T>): Promise<T> {
    return this.request<T>({ ...config, method: 'POST' })
  }

  delete<T>(config: IConfig<T>): Promise<T> {
    return this.request<T>({ ...config, method: 'DELETE' })
  }

  patch<T>(config: IConfig<T>): Promise<T> {
    return this.request<T>({ ...config, method: 'PATCH' })
  }
}
export default AxiosRequest
